package com.hn658.base.message.group.business.impl;

import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.hn658.base.message.common.contants.MessageContants;
import com.hn658.base.message.common.enums.MemberType;
import com.hn658.base.message.group.business.IGroupManager;
import com.hn658.base.message.group.dao.db.IGroupDBDAO;
import com.hn658.base.message.group.dao.db.IMemberDBDAO;
import com.hn658.base.message.group.dao.redis.IGroupRedisDAO;
import com.hn658.base.message.group.entity.GroupEO;
import com.hn658.base.message.group.entity.MemberEO;
import com.hn658.base.message.group.exception.GroupException;
import com.hn658.framework.common.AbstractBusinessObject;
import com.hn658.framework.dataaccess.pagination.GenericPage;


@Component
public class GroupManagerImpl extends AbstractBusinessObject implements IGroupManager {

	@Autowired
	IGroupDBDAO groupDBDAO;

	
	@Autowired
	IMemberDBDAO memberDBDAO;
	
	@Autowired
	IGroupRedisDAO groupRedisDAO;
	
	
	@Transactional
	@Override
	public GroupEO joinGroup(String appId, Long groupId, String uid) {
		GroupEO groupEO = findGroup(appId, groupId);
		groupEO.setPersonCount(groupEO.getPersonCount()+1);
		MemberEO member = queryMemberByGroup(appId, groupId, uid);
		if(member!=null){
			member.setIsDeleted(MessageContants.NO);
			memberDBDAO.update(member);
		}else {
			member=new MemberEO();
			member.setAppId(appId);
			member.setUid(uid);
			member.setGroupId(groupId);
			member.setIsDeleted(MessageContants.NO);
			member.setJoinTime(new Date());
			member.setMemberType(MemberType.Member.getCode() );
			updateGroup(groupEO);
			memberDBDAO.insert(member);
		}
		return groupEO;
	}

	public MemberEO queryMemberByGroup(String appId,Long groupId,String uid){
		MemberEO member = null;
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("appId", appId);
		map.put("groupId", groupId);
		map.put("uid", uid);
		List<MemberEO> memberList = memberDBDAO.selectByMap(map,"ID",false);
		if(memberList!=null&&memberList.size()>0){
			member = memberList.get(0);
		}
		return member;
	}
	
	@Override
	public boolean isGroupMember(String appId, Long groupId, String uid) {
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("appId", appId);
		map.put("groupId", groupId);
		map.put("uid", uid);
		map.put("isDeleted", false);
		List<MemberEO> memberList = memberDBDAO.selectByMap(map,"ID",false);
		if(memberList!=null&&memberList.size()==1){
			return true;
		}
		else{
			return false;
		}
	}
	
	@Override
	public GroupEO createGroup(GroupEO groupEO,String nickName) {
		if (groupEO == null) {
			throw new GroupException(GroupException.EmptyGroup);
		}
		if (groupEO.getCreateUid() == null) {
			throw new GroupException(GroupException.EmptyCreateUid);
		}
		groupEO.setCreateTime(new Date());
		groupEO.setLastUpdateTime(new Date());
		groupEO.setPersonCount(1);
		groupEO.setIsDeleted(false);
		//数据库保存群信息
		groupDBDAO.insert(groupEO);
		groupRedisDAO.saveGroup(groupEO);
		//数据库中插入该用户
		MemberEO member = new MemberEO();
		member.setGroupId(groupEO.getId());
		member.setJoinTime(new Date());
		member.setUid(groupEO.getCreateUid());
		member.setAppId(groupEO.getAppId());
		member.setMemberType(MemberType.Master.getCode());
		memberDBDAO.insert(member);
		return groupEO;
	}

	
	
	@Override
	public List<MemberEO> queryGroupMemberList(String appId, Long groupId) {
		Map<String, Object> queryParam = new HashMap<String, Object>();
		queryParam.put("appId", appId);
		queryParam.put("groupId", groupId);
		queryParam.put("isDeleted", false);
		return memberDBDAO.selectByMap(queryParam);
	}

	@Override
	public GenericPage<MemberEO> queryGroupMembers(String appId, Long groupId,
			int index, int pageSize,String orderBy,boolean isAsc) {
		Map<String, Object> queryParam = new HashMap<String, Object>();
		pageSize=(pageSize<=0?10:pageSize);
		queryParam.put("appId", appId);
		queryParam.put("groupId", groupId);
		queryParam.put("isDeleted", false);
		return memberDBDAO.selectByMap(queryParam, pageSize, index);
	}

	/*@Override
	public GenericPage<GroupEO> getMyGroups(String appId, Long uid, int index,
			int pageSize) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("appId",appId);
		map.put("uid",uid);
		map.put("isDeleted",false);
		GenericPage<MemberEO> memberPage = memberDBDAO.selectByMap(map, pageSize, index, "JOIN_TIME", false);
		List<GroupEO> groupList=new ArrayList<GroupEO>();
		for(MemberEO member: memberPage.getData()){
			groupList.add(member.getGroupEO());
		}
		return  new GenericPage<GroupEO>(index, memberPage.getTotalCount(), pageSize, groupList);
	}*/

	@Override
	public void exitTheGroup(String appId, Long groupId, String uid) {
		if(!isGroupMember(appId, groupId, uid)){
			throw new GroupException(GroupException.GroupMemberNoExist);
		}
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryMap.put("appId", appId);
		queryMap.put("id", groupId);
		queryMap.put("isDeleted", false);
		List<GroupEO> groupList = groupDBDAO.selectByMap(queryMap);
		if(groupList==null||groupList.size()!=1){
			throw new GroupException(GroupException.EmptyGroup);
		}
		GroupEO groupEO = groupList.get(0);
		queryMap.remove("id");
		queryMap.put("groupId", groupId);
		queryMap.put("uid", uid);
		List<MemberEO> memberList = memberDBDAO.selectByMap(queryMap);
		if(memberList==null||memberList.size()!=1){
			throw new GroupException(GroupException.GroupMemberNoExist);
		}
		MemberEO memberEO = memberList.get(0);
		memberEO.setIsDeleted(true);
		memberDBDAO.update(memberEO);
		groupEO.setPersonCount(groupEO.getPersonCount()-1);
		updateGroup(groupEO);
	}

	@Override
	public GroupEO findGroup(String appId, Long groupId) {
		if(groupId==null){
			throw new GroupException(GroupException.EmptyGroupId);
		}
		if(StringUtils.isBlank(appId)){
			throw new GroupException(GroupException.EmptyAppId);
		}
		GroupEO group = groupRedisDAO.getGroupById(appId,groupId);
		if(group==null){
			Map<String, Object> queryMap=new HashMap<String, Object>();
			queryMap.put("appId", appId);
			queryMap.put("id", groupId);
			queryMap.put("isDeleted", false);
			List<GroupEO> groupList = groupDBDAO.selectByMap(queryMap);
			if(groupList==null||groupList.size()<=0){
				throw new GroupException(GroupException.EmptyGroup);
			}
			group = groupList.get(0);
			groupRedisDAO.saveGroup(group);			
		}
		return group;
	}

	@Override
	public void updateGroup(GroupEO groupEO) {
		groupEO.setLastUpdateTime(new Date());
		groupDBDAO.update(groupEO);
		groupRedisDAO.saveGroup(groupEO);
	}

	@Override
	public GenericPage<GroupEO> getGroups(Map<String, Object> queryMap,int index, int pageSize) {
		return groupDBDAO.selectByMap(queryMap, pageSize, index);
	}

	@Override
	public GenericPage<GroupEO> getAllGroupsByAppId(String appId, int index,
			int pageSize) {
		Map<String, Object> queryMap=new HashMap<String, Object>();
		queryMap.put("appId", appId);
		queryMap.put("isDeleted", false);
		return getGroups(queryMap, index, pageSize);
	}
	@Transactional
	@Override
	public void disbandGroups(String appId,Long groupId,String uid) {
		GroupEO groupEO = findGroup(appId, groupId);
		if(uid.equals(groupEO.getCreateUid())){
			//获取群成员
			List<MemberEO> memberList = queryGroupMemberList(appId, groupId);
			Date date = new Date();
			if(memberList!=null&&memberList.size()>0){
				for(MemberEO member:memberList){
					member.setIsDeleted(true);
					member.setLastUpdateTime(date);
				}
				//批量踢出群用户
				memberDBDAO.batchUpdate(memberList);
			}
			//解散群
			groupEO.setIsDeleted(true);
			updateGroup(groupEO);
			
		}else{
			throw new GroupException(GroupException.NoCreateUid);
		}
	}
	
	@Override
	public int numMemberByGroup(String appId,Long groupId){
		if(appId==null||groupId==null){
			throw new GroupException(GroupException.EmptyGroup);
		}
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryMap.put("appId", appId);
		queryMap.put("groupId", groupId);
		return memberDBDAO.countByMap(queryMap);
	}

	@Override
	public List<String> queryGroupMemberIds(String appId, Long groupId) {
		Map<String, Object> queryMap=new HashMap<String, Object>();
		queryMap.put("appId", appId);
		queryMap.put("groupId", groupId);
		queryMap.put("isDeleted", false);
		return memberDBDAO.selectUidByMap(queryMap);
	}
}
